<?php
/**
 * 云账户
 * */

namespace App\Lib;

use Illuminate\Support\Facades\Log;

class CloudAccount
{
    public $requestData = [];// 接收参数

    private static $instance;
    protected $crypt3DesEcb;

    // 定义子类 api
    protected $subApi = [
        'orderRealTime' => '/api/payment/v1/order-realtime',
        'verifyBankCard' => '/authentication/verify-bankcard-three-factor',
        'getH5Url' => '/api/aic/new-economy/h5/v1/h5url'
    ];

    protected $mess = '';
    protected $timestamp = 0;

    // 配置
    protected $selfConfig = [];

    // 构造
    private function __construct($type)
    {
        if (env('APP_ENV') != 'product') {
            if($type == 1){
                $this->selfConfig = config('cloud_account_dev') ?? [];
            }else{
                $this->selfConfig = config('cloud_account_large_dev') ?? [];
            }
        } else {
            if($type == 1){
                $this->selfConfig = config('cloud_account') ?? [];
            }else{
                $this->selfConfig = config('cloud_account_large') ?? [];
            }
        }

        $this->crypt3DesEcb = new Crypt3DesEcb($this->selfConfig['appSecret']);

        $this->mess = uniqid();
        $this->timestamp = time();
    }

    /**
     * 返回实例
     * */
    static public function getInstance($type = 0)
    {
        self::$instance = new self($type);

        return self::$instance;
    }

    /**
     * 加密
     * */
    protected function encrypt($params = [])
    {
        $encryptStr = $this->crypt3DesEcb->encrypt(json_encode($params));

        return $encryptStr;
    }

    /**
     * 解密本地加密数据
     * */
    protected function decrypt($encryptStr = '')
    {
        $decrypt = $this->crypt3DesEcb->decrypt($encryptStr);
        if (is_string($decrypt)) {
            $decrypt = json_decode($decrypt, true);
        }

        return $decrypt;
    }

    /**
     * 生成签名
     * */
    protected function generateSign($encryptStr)
    {
        // 此处不要用 http_build_query() , 云账户Api接口局限字符硬编码

        $inputParams = 'data=' . $encryptStr . '&mess=' . $this->mess . '&timestamp=' . $this->timestamp . '&key=' . $this->selfConfig['appKey'];
        $signStr = hash_hmac('sha256', $inputParams, $this->selfConfig['appKey']);

        return $signStr;
    }

    /**
     * 请求格式化
     * */
    protected function curlFormat($params, $api, $requestId ,$method='post')
    {
        // 加密串
        $encryptStr = $this->encrypt($params);

        // 签名
        $signStr = $this->generateSign($encryptStr);
        if($method == 'post'){
            $result = curlRequest(
                $this->selfConfig['domain'] . $this->subApi[$api],
                [
                    'data' => $encryptStr,
                    'mess' => $this->mess,
                    'timestamp' => $this->timestamp,
                    'sign' => $signStr,
                    'sign_type' => 'sha256',
                ],
                false,
                [
                    'dealer-id:' . $this->selfConfig['dealerId'],
                    'request-id:local-timestamp:' . $this->timestamp . '-' . $requestId,
                ]
            );
        }else{
            $result = $this->curl_request_get(
                'https://api-aic.yunzhanghu.com' . $this->subApi[$api],
                [
                    'data' => $encryptStr,
                    'mess' => $this->mess,
                    'timestamp' => $this->timestamp,
                    'sign' => $signStr,
                    'sign_type' => 'sha256',
                ],
                [
                    'dealer-id:' . $this->selfConfig['dealerId'],
                    'request-id:local-timestamp:' . $this->timestamp . '-' . $requestId,
                ]
            );


        }


        return $result;
    }

    /**
     * 校验银行卡
     *
     * 银⾏卡三要素验证
     * */
    public function verifyBankCard()
    {
        // 请求ID
        $requestId = 'id-card-' . $this->requestData['idcard_number'];

        $result = $this->curlFormat([
            'card_no' => $this->requestData['bank_no'],// 银行卡号
            'id_card' => $this->requestData['idcard_number'],// 银行开户身份证
            'real_name' => $this->requestData['idcard_name'],// 银行卡开户姓名
        ], 'verifyBankCard', $requestId);

        return $result;
    }

    /**
     * 解密回调数据
     * */
    public function decryptNotifyData()
    {
        if (empty($this->requestData['data']) or !is_string($this->requestData['data'])) {
            return false;
        }

        $decryptData = $this->decrypt($this->requestData['data']);
        if (!is_array($decryptData)) {
            return false;
        }

        return $decryptData;
    }

    /**
     * 获取人脸识别地址
     * */
    public function getH5Url()
    {
        $this->requestData['userId'] = strval($this->requestData['userId']);
        // 请求ID
        $requestId = 'user-id-' . $this->requestData['userId'];

        $result = $encryptStr = $this->curlFormat([
            'dealer_id' => $this->selfConfig['dealerId'],
            'broker_id' => $this->selfConfig['brokerId'],
            'dealer_user_id' => $this->requestData['userId'],
            'client_type' => 1,
            'return_url' => $this->requestData['returnUrl'],// 跳转页面地址
            'notify_url' => $this->selfConfig['notifyUrl'],// 回调地址
        ], 'getH5Url', $requestId ,'get');

        return $result;
    }

    public function __destruct()
    {
        // TODO: Implement __destruct() method.
    }

    function curl_request_get($action, $params,$header = [])
    {
        $ch = curl_init();
        $action .= strpos($action, '?') === false ? '?' : '&';
        $action .= build_query($params);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_URL, $action);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //处理http证书问题
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $ret = curl_exec($ch);
        if (false === $ret) {
            $ret = curl_errno($ch);
        }
        curl_close($ch);
        return $ret;
    }
}